<?php
/**
 * Created by PhpStorm.
 * User: huyang
 * Date: 16/10/29
 * Time: 下午8:02
 */

namespace App\Http\Repositories\Services\Impls;


use App\Exceptions\ServiceException;
use App\Http\Constants\CommonExceptionConstants;
use App\Http\Constants\MessageExceptionConstants;
use App\Http\Repositories\Daos\IMessageDao;
use App\Http\Repositories\Eloquent\Message;
use App\Http\Repositories\Services\IMessage;
use App\Util\Helper;
use Carbon\Carbon;
use Toplan\PhpSms\Facades\Sms;

class MessageService implements IMessage
{

    private $messageDao;

    //发送频率限制(秒)
    private $limit = 60;

    //短信验证码有效期
    private $valid = 3000;


    public function __construct(IMessageDao $messageDao) {
        $this->messageDao = $messageDao;
    }


    public function send($mobile, $param, $code = '') {

        $data = [];

        $data['mobile'] = $mobile;
        $data['param'] = json_encode($param);
        $data['code'] = $code;

        //验证手机
        if (!Helper::isMobile($mobile)) {
            throw new ServiceException(CommonExceptionConstants::getKey('mobile_is_not_valid'));
        }

        //验证手机是否频繁发送
        if ($lastResult = $this->messageDao->findLastMsgByMobile($mobile)) {
            $lastResult = $lastResult->toArray();
            if (strtotime($lastResult['created_at']) + $this->limit > Carbon::now()->getTimestamp()) {
                throw new ServiceException(MessageExceptionConstants::getKey('msg_send_too_frequently'));
            }
        }

        $dao = new Message();
        $dao->mobile = $mobile;
        $dao->param = json_encode($param);
        $dao->code = $code;
        $dao->save();

        if ($dao) {

            switch ($code) {
                case 'Verification';
                    $smsId = 'SMS_151545017';
                    break;
                default:
                    throw new ServiceException(MessageExceptionConstants::getKey('unknown_sms_id'));
                    break;
            }

            $templates = ['Aliyun' => $smsId];

            $response = Sms::make()->to($mobile)->template($templates)->data($param)->send();

            if (array_key_exists('success',$response) && $response['success'] == 'true') {
                return $dao->id;
            } else {
                $dao->success = 0;
                $dao->save();
                $message = $response['logs'][0]['result']['info'];
                if (Helper::json($message)) {
                    $message = json_decode($message);
                    $message = $message->Message;
                }
                throw new ServiceException(MessageExceptionConstants::getMsg($message));
            }

        } else {
            throw new ServiceException(MessageExceptionConstants::getKey('msg_save_fail'));
        }
    }

    public function validate($mobile, $code)
    {

        $data = $this->messageDao->findByMobile($mobile, $this->valid);

        if (!$data) {
            throw new ServiceException(MessageExceptionConstants::getKey('msg_find_fail'));
        }

        $match = false;

        foreach ($data as $item) {
            if ($item->num > 5) {
                continue;
            }
            $param = json_decode($item->param);
            if (property_exists($param, 'code')) {
                if ($code == $param->code) {
                    $item->consume = 1;
                    $match = true;
                }
            }
            $item->num = $item->num + 1;
            $item->save();
        }

        if (!$match) {
            throw new ServiceException(MessageExceptionConstants::getKey('msg_code_match_fail'));
        }

    }

}